<template>
    <div class="min-h-screen bg-gray-50 py-8">
        <div class="max-w-6xl mx-auto px-4">
            <header class="flex items-center justify-between mb-6">
                <h1 class="text-2xl font-semibold text-gray-800">八八小店</h1>
                <div class="flex items-center gap-4">
                    <div class="hidden sm:flex items-center text-sm text-gray-500">共 {{ total }} 件商品</div>
                    <nuxt-link to="/shop/result" class="text-sm text-blue-600 hover:underline">订单查询</nuxt-link>
                </div>
            </header>

            <div class="mb-6">
                <div class="flex gap-3">
                    <input
                        v-model="search"
                        @keyup.enter="fetchProducts(1)"
                        placeholder="搜索商品名或说明"
                        class="flex-1 px-4 py-2 border border-gray-200 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-200"
                    />
                    <button
                        @click="fetchProducts(1)"
                        class="px-4 py-2 bg-blue-600 text-white rounded-lg shadow hover:bg-blue-700"
                    >搜索</button>
                </div>
            </div>

            <section>
                <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
                    <div v-for="p in products" :key="p.id" class="bg-white rounded-xl shadow-md overflow-hidden hover:shadow-lg transition">
                        <nuxt-link :to="`/shop/product?id=${p.id}`" class="block">
                            <div class="h-44 bg-white flex items-center justify-center overflow-hidden relative">
                                <img v-if="p.image_base64" :src="imgSrc(p.image_base64)" alt="商品图片" @error="onImgError" class="w-full h-full object-cover" />
                                <div v-else class="w-full h-full flex items-center justify-center">
                                    <svg viewBox="0 0 200 120" xmlns="http://www.w3.org/2000/svg" class="w-full h-full">
                                        <defs>
                                            <linearGradient id="g1" x1="0" x2="1">
                                                <stop offset="0" stop-color="#f8fafc" />
                                                <stop offset="1" stop-color="#eef2ff" />
                                            </linearGradient>
                                            <linearGradient id="g2" x1="0" x2="1">
                                                <stop offset="0" stop-color="#60a5fa" />
                                                <stop offset="1" stop-color="#7c3aed" />
                                            </linearGradient>
                                        </defs>
                                        <rect x="6" y="6" width="188" height="108" rx="12" fill="url(#g1)" />
                                        <rect x="24" y="22" width="152" height="76" rx="8" fill="#ffffff" opacity="0.6" />

                                        <!-- shopping bag icon -->
                                        <g transform="translate(76,34)">
                                            <rect x="4" y="18" width="48" height="28" rx="4" fill="url(#g2)" opacity="0.14" />
                                            <path d="M8 18c0-6 4-8 16-8s16 2 16 8v2H8v-2z" fill="url(#g2)" opacity="0.95" />
                                            <path d="M16 12v-2a8 8 0 0116 0v2" stroke="#fff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" fill="none" opacity="0.95" />
                                        </g>

                                        <!-- subtle decorative dots -->
                                        <g fill="#c7d2fe" opacity="0.4">
                                            <circle cx="50" cy="36" r="2.6" />
                                            <circle cx="146" cy="36" r="2.6" />
                                            <circle cx="98" cy="84" r="2.6" />
                                        </g>

                                        <text x="100" y="102" font-size="11" fill="#94a3b8" text-anchor="middle" font-family="Inter, ui-sans-serif, system-ui">Loading....</text>
                                    </svg>
                                </div>
                            </div>
                            <div class="p-4">
                                <h3 class="text-lg font-medium text-gray-800 truncate">{{ p.product_name }}</h3>
                                <p class="text-sm text-gray-500 mt-1 truncate">{{ short(p.product_info || p.detail) }}</p>
                                <div class="mt-4 flex items-center justify-between">
                                    <div class="text-red-500 font-semibold">¥{{ p.price }}</div>
                                    <div>
                                        <nuxt-link :to="`/shop/product?id=${p.id}`" class="text-blue-600 text-sm hover:underline">查看详情</nuxt-link>
                                    </div>
                                </div>
                            </div>
                        </nuxt-link>
                    </div>
                </div>
            </section>

            <footer class="mt-8 flex items-center justify-center gap-4 text-gray-600">
                <button :disabled="page<=1" @click="fetchProducts(page-1)" class="px-3 py-1 rounded-md border border-gray-200 bg-white disabled:opacity-50">上一页</button>
                <span>第 {{ page }} 页，共 {{ Math.ceil(total/pageSize) }} 页</span>
                <button :disabled="page*pageSize>=total" @click="fetchProducts(page+1)" class="px-3 py-1 rounded-md border border-gray-200 bg-white disabled:opacity-50">下一页</button>
            </footer>
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useHead } from '#imports'
useHead({ title: '八八小店' })

const products = ref([])
const page = ref(1)
const pageSize = ref(9)
const total = ref(0)
const search = ref('')

function short(text) {
    if (!text) return ''
    return text.length > 80 ? text.slice(0, 80) + '…' : text
}

function renderImage(b64) {
    if (!b64) return ''
    // if it already includes data:image prefix, render directly
    if (b64.startsWith('data:')) return `<img src="${b64}" alt="img" />`
    return `<img src="data:image/png;base64,${b64}" alt="img" />`
}

function imgSrc(b64) {
    if (!b64) return ''
    if (b64.startsWith('data:')) return b64
    return `data:image/png;base64,${b64}`
}

function onImgError(e) {
    // 如果图片加载失败，隐藏该 img 元素，保留空白占位
    try { e.target.style.display = 'none' } catch (err) { /* ignore */ }
}

async function fetchProducts(p = 1) {
    page.value = p
    try {
        const q = new URLSearchParams({ page: String(page.value), pageSize: String(pageSize.value) })
        if (search.value) q.append('search', search.value)
    const res = await fetch(`/api/products?${q.toString()}`)
        const json = await res.json()
        products.value = json.data || []
        total.value = json.total || 0
    } catch (e) {
        console.error(e)
    }
}

onMounted(() => {
    fetchProducts(1)
})
</script>

<style scoped>
.shop-page{ padding:20px }
.search-row{ display:flex; gap:8px; margin-bottom:16px }
.search-row input{ flex:1; padding:8px }
.grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:20px }
.card{ border:1px solid #f0f0f0; border-radius:12px; padding:12px; display:flex; flex-direction:column; min-height:220px; background:#fff; box-shadow:0 6px 18px rgba(15,23,42,0.06); transition:transform .18s ease, box-shadow .18s ease }
.card:hover{ transform:translateY(-6px); box-shadow:0 12px 30px rgba(15,23,42,0.09) }
.img{ width:100%; height:140px; display:block; overflow:hidden; border-radius:8px; background:linear-gradient(180deg,#fafafa,#f3f5f7); display:flex; align-items:center; justify-content:center }
.img img{ width:100%; height:140px; object-fit:cover; border-radius:6px }
.price{ color:#e55353; font-weight:600 }
.actions{ margin-top:auto }
.pager{ margin-top:16px; display:flex; gap:12px; align-items:center }
</style>